import traceback
import json
from fastapi import Request, FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from backend.models.request_log import RequestLog

def parse_browser(user_agent: str) -> str:
    ua = user_agent.lower()
    if "edg" in ua:
        return "Edge"
    if "chrome" in ua and "chromium" not in ua:
        return "Chrome"
    if "safari" in ua and "chrome" not in ua:
        return "Safari"
    if "firefox" in ua:
        return "Firefox"
    if "opera" in ua or "opr" in ua:
        return "Opera"
    if "msie" in ua or "trident" in ua:
        return "IE"
    return "Other"

class RequestLogMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = None
        try:
            response = await call_next(request)
            status_code = response.status_code
        except Exception as e:
            status_code = 500
            raise
        finally:
            ip = request.client.host if request.client else "unknown"
            user_agent = request.headers.get("user-agent", "unknown")
            browser = parse_browser(user_agent)
            path = str(request.url.path)
            method = request.method
            # 获取请求参数
            params = {}
            try:
                if method in ("POST", "PUT", "PATCH"):
                    body = await request.body()
                    if body:
                        try:
                            params = json.loads(body.decode("utf-8"))
                        except Exception:
                            params = {"raw": body.decode("utf-8", errors="ignore")}
                else:
                    params = dict(request.query_params)
            except Exception:
                params = {}
            # 异步写入日志表
            try:
                await RequestLog.create(
                    ip_address=ip,
                    user_agent=user_agent,
                    browser=browser,
                    path=path,
                    method=method,
                    status_code=status_code,
                    params=params
                )
            except Exception:
                # 避免日志写入异常影响主流程
                traceback.print_exc()
        return response

def register_request_log_middleware(app: FastAPI):
    app.add_middleware(RequestLogMiddleware)
